Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compose shouldForwardProp #670

Merged
merged 2 commits into from
May 25, 2018
Merged

compose shouldForwardProp #670

merged 2 commits into from
May 25, 2018

Conversation

brentertz
Copy link
Contributor

@brentertz brentertz commented May 22, 2018

What:

Compose shouldForwardProp on composed styled components

Why:

I am investigating the migration of a library that is currently built on Glamorous, which may soon be deprecated.

When composing styled components, I have noticed that Emotion and Glamorous seem to work differently. Glamorous respects the inner component's filtered props, whereas Emotion does not appear to.

In Mineral, in our emotion branch, we are attempting to provide a wrapper around styled, which adds a custom shouldForwardProp that enables filtering of props based on the HTML tag being rendered, a feature that also exists in Glamorous. This works fine until styled components are composed, at which point the outer shouldForwardProp takes precedence and the inner one is completely ignored, thus the resulting component does not receive the expected props.

I see that this issue was also discussed in
#659

Is this functionality desired, planned, achievable, or other?

How:

Implemented updates as suggested by @mitchellhamilton

Checklist:

  • Documentation
  • Tests
  • Code complete

@emmatown
Copy link
Member

I didn't totally understand this issue before but I get it now, below is how I think we could solve it. If this solves your issue, add this to the PR and I'll merge it.

diff --git a/packages/create-emotion-styled/src/index.js b/packages/create-emotion-styled/src/index.js
index 4ac2ee9..cf6126d 100644
--- a/packages/create-emotion-styled/src/index.js
+++ b/packages/create-emotion-styled/src/index.js
@@ -25,11 +25,18 @@ function createEmotionStyled(emotion: Emotion, view: ReactType) {
     let identifierName
     let stableClassName
     let shouldForwardProp
+    let customShouldForwardProp
     if (options !== undefined) {
       staticClassName = options.e
       identifierName = options.label
       stableClassName = options.target
-      shouldForwardProp = options.shouldForwardProp
+      shouldForwardProp = customShouldForwardProp =
+        tag.__emotion_forwardProp && options.shouldForwardProp
+          ? propName =>
+              tag.__emotion_forwardProp(propName) &&
+              // $FlowFixMe
+              options.shouldForwardProp(propName)
+          : options.shouldForwardProp
     }
     const isReal = tag.__emotion_real === tag
     const baseTag =
@@ -75,6 +82,7 @@ function createEmotionStyled(emotion: Emotion, view: ReactType) {
         static __emotion_styles: Interpolations
         static __emotion_base: Styled
         static __emotion_target: string
+        static __emotion_forwardProp: void | (string => boolean)
         static withComponent: (ElementType, options?: StyledOptions) => any

         componentWillMount() {
@@ -148,6 +156,7 @@ function createEmotionStyled(emotion: Emotion, view: ReactType) {
       Styled.__emotion_styles = styles
       Styled.__emotion_base = baseTag
       Styled.__emotion_real = Styled
+      Styled.__emotion_forwardProp = customShouldForwardProp
       Object.defineProperty(Styled, 'toString', {
         enumerable: false,
         value() {

@brentertz
Copy link
Contributor Author

Hello and thank you for the quick reply and suggested solution. I am currently testing it locally and will report back this week. Initial results look promising. 😄

@codecov
Copy link

codecov bot commented May 23, 2018

Codecov Report

Merging #670 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted Files Coverage Δ
packages/create-emotion-styled/src/index.js 100% <100%> (ø) ⬆️

if (options !== undefined) {
staticClassName = options.e
identifierName = options.label
stableClassName = options.target
shouldForwardProp = options.shouldForwardProp
shouldForwardProp = customShouldForwardProp =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to keep 2 variables for this?

@brentertz
Copy link
Contributor Author

Updated to remove extra customShouldForwardProp variable.

This appears to be working well across all of the components and website in mineral-ui.

Thanks again for your solution and responsiveness.

@Andarist
Copy link
Member

LGTM, can't merge it though, so you'll have to w8 for @mitchellhamilton 😉

@brentertz brentertz changed the title Add failing test for shouldForwardProp composition compose shouldForwardProp May 24, 2018
Copy link
Member

@emmatown emmatown left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!!

@emmatown emmatown merged commit 75af5b1 into emotion-js:master May 25, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants